using CfgStory;
using Cysharp.Threading.Tasks;
using System;
using System.Collections.Generic;

namespace IQIGame.Onigao.GamePlay
{
    /// <summary>
    /// 剧情播放的上下文
    /// </summary>
    public class StoryPlayContext
    {
        public TbCfgStoryShow tbStory { private set; get; }
        // 当前所在的行数(0开始，-1结束)
        public int currentIndex { get; private set; }
        public string storyName => tbStory.StoryName;

        private Func<List<int>, List<int>, UniTask> _sendServiceFunc;

        // 当前这一片段数据(一个对话画面)
        private CfgStoryShow _curStoryFrament;
        // 当前选项的索引(-1无，从0开始)
        private int _curChoiceOptionIndex;

        /// <summary>
        /// 为服务器准备的上次服务之间到这次之间的选择
        /// </summary>
        private readonly List<int> _idForOptions = new List<int>();
        private readonly List<int> _selectionIndexes = new List<int>();

        /// <summary>
        /// 是否需要强制发送服务选项
        /// </summary>
        private bool _needSendServiceForce;

        /// <summary>
        /// 是否跳过剧情
        /// </summary>
        //public bool isSkiped;

        public bool isSendedEndService { private set; get; }

        public StoryPlayContext(TbCfgStoryShow tbStory, int jumpCid)
        {
            this.tbStory = tbStory;
            if (jumpCid <= 0)
            {
                this.currentIndex = 0;
            }
            else
            {
                this.currentIndex = GetNewIndexByJumpId(jumpCid);
            }
        }

        public void InitMessageSend(Func<List<int>, List<int>, UniTask> sendServiceFunc)
        {
            this._sendServiceFunc = sendServiceFunc;
        }


        /// <summary>
        /// 进入下一行剧情片段索引
        /// </summary>
        /// <returns></returns>
        public StoryPlayContext NextIndex()
        {
            this.currentIndex++;
            return this;
        }

        /// <summary>
        /// 跳转到指定的剧情片段索引
        /// </summary>
        /// <param name="newIndex"></param>
        /// <returns></returns>
        public StoryPlayContext JumpToIndex(int newIndex)
        {
            this.currentIndex = newIndex;
            return this;
        }

        public bool IsStoryEnd()
        {
            if (currentIndex >= tbStory.DataList.Count || currentIndex < 0)
            {
                // 结束
                return true;
            }
            return false;
        }

        /// <summary>
        /// 进入当前索引的故事片段配置
        /// </summary>
        /// <param name="storyCfg"></param>
        /// <returns></returns>
        public bool EnterCurrentStoryFragmentCfg(out CfgStory.CfgStoryShow storyCfg)
        {
            this._curChoiceOptionIndex = -1;
            if (IsStoryEnd())
            {
                _curStoryFrament = storyCfg = null;
                return false;
            }
            _curStoryFrament = storyCfg = tbStory.DataList[this.currentIndex];
            return true;
        }

        public int GetNewIndexByJumpId(int jumpId, int defaultValue = -1)
        {
            if (jumpId > 0)
            {
                if (tbStory.Id2IndexMapping.TryGetValue(jumpId, out var nextIndex))
                {
                    return nextIndex;
                }
            }
            return defaultValue;
        }

        public void SaveChoiceOption(int id, int selectIndex)
        {
            this._curChoiceOptionIndex = selectIndex;
            this._idForOptions.Add(id);
            this._selectionIndexes.Add(selectIndex);
        }

        /// <summary>
        /// 检测和发送
        /// </summary>
        public bool CheckerStoryService()
        {
            if (_needSendServiceForce)
            {
                _needSendServiceForce = false;
                return true;
            }
            if (this._curStoryFrament == null)
            {
                return false;
            }
            IReadOnlyList<int> services = null;
            if (this._curChoiceOptionIndex < 0)
            {
                // 没有真实选项的时候
                services = this._curStoryFrament.Service.Count > 0 ? this._curStoryFrament.Service[0] : null;
            }
            else
            {
                // 有真实的选项的时候
                services = this._curStoryFrament.Service.Count > this._curChoiceOptionIndex ? this._curStoryFrament.Service[this._curChoiceOptionIndex] : null;
                var jumpId = this._curStoryFrament.JumpID[this._curChoiceOptionIndex];
                if (jumpId == -1)
                {
                    this.isSendedEndService = true; //结束服务标记
                    return true;
                }
            }

            // 如果是结束，也需要发送
            if (this._curStoryFrament.JumpID.Count > 0 && this._curStoryFrament.JumpID[0] == -1)
            {
                this.isSendedEndService = true; //结束服务标记
                if (this._curChoiceOptionIndex < 0)
                {
                    // 如果结束没有真实选项，凭空制造一个选项
                    this._idForOptions.Add(this._curStoryFrament.Id);
                    this._selectionIndexes.Add(0);
                }
                return true;
            }

            if (services == null || services.Count == 0)
            {
                // 无服务的情况
                return false;
            }

            // 有服务，但是无选项的情况
            if (this._curChoiceOptionIndex < 0)
            {
                // 也是凭空造一个选项
                this._idForOptions.Add(this._curStoryFrament.Id);
                this._selectionIndexes.Add(0);
            }
            return true;
        }

        public async UniTask SendStoryService()
        {
            await _sendServiceFunc(this._idForOptions, this._selectionIndexes);
            this._idForOptions.Clear();
            this._selectionIndexes.Clear();
        }

        /// <summary>
        /// 跳过剧情，跳转到下一个有分支的剧情
        /// </summary>
        public int SkipStory()
        {
            if (this.currentIndex < 0)
            {
                // 已经结束
                return -1;
            }
            var index = this.currentIndex;
            // 找到第一个分支或结束
            while (true)
            {
                if (index >= tbStory.DataList.Count || index < 0)
                {
                    // 当前已经是最后一条了结束
                    return -1;
                }
                var storyFrament = tbStory.DataList[index];
                if (storyFrament.JumpID.Count > 1)
                {
                    // 当前有选项
                    return index;
                }
                bool tmpService = false;
                if (storyFrament.Service.Count > 0 && storyFrament.Service[0].Count > 0)
                {
                    // 当前有服务
                    tmpService = true;
                    // 需要强制发送服务标记
                    _needSendServiceForce = true;
                    SaveChoiceOption(storyFrament.Id, 0);
                    this._curChoiceOptionIndex = -1;
                }
                if (storyFrament.JumpID.Count > 0 && storyFrament.JumpID[0] == -1)
                {
                    // 是结束
                    if (!tmpService)
                    {
                        // 选项
                        SaveChoiceOption(storyFrament.Id, 0);
                        this._curChoiceOptionIndex = -1;
                    }
                    isSendedEndService = true; //结束服务标记
                    return -1;
                }

                // 进入下一个
                if (storyFrament.JumpID.Count == 0)
                {
                    index++;
                }
                else
                {
                    index = tbStory.Id2IndexMapping[storyFrament.JumpID[0]];
                }
            }
        }

    }
}
